using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.Extensions.Primitives;
using StackExchange.Redis;
using Volo.Abp;
using Volo.Abp.Caching;
using Volo.Abp.Modularity;

namespace CKY.AgentPlatform.Caching
{
    /// <summary>
    /// 缓存配置服务
    /// </summary>
    public class CacheConfigurationService : ITransientDependency
    {
        private readonly IDistributedCache _distributedCache;
        private readonly IConnectionMultiplexer _redis;
        private readonly ILogger<CacheConfigurationService> _logger;
        private readonly CacheOptions _cacheOptions;

        public CacheConfigurationService(
            IDistributedCache distributedCache,
            IConnectionMultiplexer redis,
            ILogger<CacheConfigurationService> logger,
            IOptions<CacheOptions> cacheOptions)
        {
            _distributedCache = distributedCache;
            _redis = redis;
            _logger = logger;
            _cacheOptions = cacheOptions.Value;
        }

        /// <summary>
        /// 配置缓存设置
        /// </summary>
        public async Task ConfigureCacheAsync()
        {
            try
            {
                _logger.LogInformation("开始配置缓存设置");

                // 配置Redis连接
                await ConfigureRedisAsync();

                // 设置默认缓存策略
                // await SetDefaultCachePoliciesAsync();

                // 预热缓存
                // await WarmUpCacheAsync();

                _logger.LogInformation("缓存配置完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "缓存配置失败");
                throw;
            }
        }

        /// <summary>
        /// 配置Redis设置
        /// </summary>
        private async Task ConfigureRedisAsync()
        {
            try
            {
                var redisOptions = _cacheOptions.RedisOptions;
                if (redisOptions == null)
                {
                    _logger.LogWarning("Redis配置未找到，跳过Redis配置");
                    return;
                }

                // 测试Redis连接
                var redis = await ConnectionMultiplexer.ConnectAsync(redisOptions.ConnectionString);
                
                if (redis.IsConnected)
                {
                    _logger.LogInformation("Redis连接成功");
                    
                    // 配置Redis设置
                    var db = redis.GetDatabase();
                    
                    // 设置最大内存策略
                    if (redisOptions.MaxMemoryPolicy != null)
                    {
                        await db.ExecuteAsync("CONFIG", "SET", "maxmemory-policy", redisOptions.MaxMemoryPolicy);
                    }
                    
                    // 设置超时时间
                    if (redisOptions.Timeout > 0)
                    {
                        await db.ExecuteAsync("CONFIG", "SET", "timeout", redisOptions.Timeout.ToString());
                    }
                    
                    // 设置慢查询日志
                    await db.ExecuteAsync("CONFIG", "SET", "slowlog-log-slower-than", "10000"); // 10ms
                    await db.ExecuteAsync("CONFIG", "SET", "slowlog-max-len", "128");
                }
                else
                {
                    _logger.LogWarning("Redis连接失败");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Redis配置失败");
            }
        }

        /// <summary>
        /// 设置默认缓存策略
        /// </summary>
        private async Task SetDefaultCachePoliciesAsync()
        {
            try
            {
                var cacheService = new DistributedCacheService(
                    _distributedCache,
                    _logger,
                    NullCurrentTenant.Instance
                );

                // 设置默认缓存过期时间
                await cacheService.SetAsync("config:default:expiration", CacheExpiration.Medium);
                
                // 设置缓存策略
                var policies = new System.Collections.Generic.Dictionary<string, TimeSpan>
                {
                    { "config:user:expiration", CacheExpiration.Session },
                    { "config:agent:expiration", CacheExpiration.Short },
                    { "config:system:expiration", CacheExpiration.Long },
                    { "config:statistics:expiration", CacheExpiration.Statistics }
                };

                foreach (var policy in policies)
                {
                    await cacheService.SetAsync(policy.Key, policy.Value.TotalSeconds);
                }

                _logger.LogInformation("默认缓存策略设置完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置默认缓存策略失败");
            }
        }

        /// <summary>
        /// 预热缓存
        /// </summary>
        private async Task WarmUpCacheAsync()
        {
            try
            {
                var cacheService = new DistributedCacheService(
                    _distributedCache,
                    _logger,
                    NullCurrentTenant.Instance
                );

                // 预热系统配置
                await cacheService.SetAsync("warmup:system:config", new SystemConfig
                {
                    CacheEnabled = true,
                    CacheTimeout = CacheExpiration.Medium.TotalSeconds,
                    CacheVersion = "1.0.0",
                    WarmUpTime = DateTime.UtcNow
                }, CacheExpiration.Long);

                // 预热用户权限配置
                await cacheService.SetAsync("warmup:permissions:config", new PermissionsConfig
                {
                    DefaultPermissions = new[] { "View", "Create", "Edit" },
                    AdminPermissions = new[] { "Admin", "Manage", "Delete" },
                    CacheEnabled = true
                }, CacheExpiration.Long);

                _logger.LogInformation("缓存预热完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "缓存预热失败");
            }
        }

        /// <summary>
        /// 获取缓存状态
        /// </summary>
        public async Task<CacheStatus> GetCacheStatusAsync()
        {
            try
            {
                var status = new CacheStatus
                {
                    Timestamp = DateTime.UtcNow,
                    DistributedCacheEnabled = _cacheOptions.DistributedCacheEnabled,
                    RedisEnabled = _cacheOptions.RedisOptions != null
                };

                // 检查分布式缓存状态
                if (status.DistributedCacheEnabled)
                {
                    try
                    {
                        status.DistributedCacheHealthy = await _distributedCache.GetStringAsync("warmup:system:config") != null;
                    }
                    catch
                    {
                        status.DistributedCacheHealthy = false;
                    }
                }

                // 检查Redis状态
                if (status.RedisEnabled)
                {
                    try
                    {
                        status.RedisHealthy = _redis.IsConnected;
                    }
                    catch
                    {
                        status.RedisHealthy = false;
                    }
                }

                return status;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取缓存状态失败");
                return new CacheStatus { Timestamp = DateTime.UtcNow };
            }
        }
    }

    /// <summary>
    /// 缓存后台服务
    /// </summary>
    public class CacheBackgroundService : BackgroundService
    {
        private readonly IServiceProvider _serviceProvider;
        private readonly ILogger<CacheBackgroundService> _logger;
        private readonly CacheOptions _cacheOptions;

        public CacheBackgroundService(
            IServiceProvider serviceProvider,
            ILogger<CacheBackgroundService> logger,
            IOptions<CacheOptions> cacheOptions)
        {
            _serviceProvider = serviceProvider;
            _logger = logger;
            _cacheOptions = cacheOptions.Value;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            _logger.LogInformation("缓存后台服务启动");

            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    await PerformMaintenanceTasksAsync(stoppingToken);
                    await Task.Delay(TimeSpan.FromMinutes(_cacheOptions.MaintenanceInterval), stoppingToken);
                }
                catch (OperationCanceledException)
                {
                    // 正常退出
                    break;
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex, "缓存后台服务执行失败");
                    await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
                }
            }

            _logger.LogInformation("缓存后台服务停止");
        }

        /// <summary>
        /// 执行维护任务
        /// </summary>
        private async Task PerformMaintenanceTasksAsync(CancellationToken stoppingToken)
        {
            try
            {
                using var scope = _serviceProvider.CreateScope();
                
                var cacheService = scope.ServiceProvider.GetService<DistributedCacheService>();
                var redisCacheService = scope.ServiceProvider.GetService<RedisCacheService>();
                
                if (cacheService != null)
                {
                    // 清理过期缓存
                    await CleanupExpiredCacheAsync(cacheService);
                    
                    // 更新统计信息
                    await UpdateStatisticsAsync(cacheService);
                }

                if (redisCacheService != null)
                {
                    // Redis维护
                    await PerformRedisMaintenanceAsync(redisCacheService);
                }

                _logger.LogDebug("缓存维护任务完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "缓存维护任务失败");
            }
        }

        /// <summary>
        /// 清理过期缓存
        /// </summary>
        private async Task CleanupExpiredCacheAsync(DistributedCacheService cacheService)
        {
            try
            {
                // 清理临时缓存
                await cacheService.RemoveAsync("temp:*");
                
                // 清理过期的统计信息
                await cacheService.RemoveAsync("statistics:temp:*");
                
                _logger.LogDebug("过期缓存清理完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "清理过期缓存失败");
            }
        }

        /// <summary>
        /// 更新统计信息
        /// </summary>
        private async Task UpdateStatisticsAsync(DistributedCacheService cacheService)
        {
            try
            {
                var now = DateTime.UtcNow;
                var stats = new CacheStatistics
                {
                    Timestamp = now,
                    OperationCount = await GetOperationCountAsync(cacheService),
                    CacheHitRate = await GetCacheHitRateAsync(cacheService),
                    MemoryUsage = await GetMemoryUsageAsync(cacheService)
                };

                await cacheService.SetAsync("statistics:current", stats, CacheExpiration.Statistics);
                
                _logger.LogDebug("缓存统计信息更新完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新缓存统计信息失败");
            }
        }

        /// <summary>
        /// 执行Redis维护
        /// </summary>
        private async Task PerformRedisMaintenanceAsync(RedisCacheService redisCacheService)
        {
            try
            {
                // 获取Redis统计信息
                var redisStats = await redisCacheService.GetStatisticsAsync();
                
                // 检查内存使用率
                if (redisStats.UsedMemory > 0 && redisStats.MaxMemory > 0)
                {
                    var usagePercentage = (double)redisStats.UsedMemory / redisStats.MaxMemory * 100;
                    if (usagePercentage > 80)
                    {
                        _logger.LogWarning("Redis内存使用率过高: {UsagePercentage}%", usagePercentage);
                        
                        // 清理不必要的缓存
                        await redisCacheService.ClearPatternAsync("temp:*");
                        await redisCacheService.ClearPatternAsync("debug:*");
                    }
                }

                // 检查命中率
                if (redisStats.HitRatePercentage < 50)
                {
                    _logger.LogWarning("Redis缓存命中率过低: {HitRatePercentage}%", redisStats.HitRatePercentage);
                }

                _logger.LogDebug("Redis维护完成");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Redis维护失败");
            }
        }

        private async Task<long> GetOperationCountAsync(DistributedCacheService cacheService)
        {
            return await cacheService.GetLongAsync("statistics:operations:count");
        }

        private async Task<double> GetCacheHitRateAsync(DistributedCacheService cacheService)
        {
            return await cacheService.GetDoubleAsync("statistics:hit:rate");
        }

        private async Task<long> GetMemoryUsageAsync(DistributedCacheService cacheService)
        {
            return await cacheService.GetLongAsync("statistics:memory:usage");
        }
    }

    /// <summary>
    /// 缓存配置
    /// </summary>
    public class CacheOptions
    {
        public bool DistributedCacheEnabled { get; set; } = true;
        public RedisOptions RedisOptions { get; set; }
        public int MaintenanceInterval { get; set; } = 5; // 分钟
        public bool EnableResponseCaching { get; set; } = true;
        public bool EnableQueryCaching { get; set; } = true;
        public int DefaultExpirationMinutes { get; set; } = 30;
    }

    /// <summary>
    /// Redis配置
    /// </summary>
    public class RedisOptions
    {
        public string ConnectionString { get; set; } = "localhost:6379";
        public string InstanceName { get; set; } = "AgentPlatform";
        public int Database { get; set; } = 0;
        public string MaxMemoryPolicy { get; set; } = "allkeys-lru";
        public int Timeout { get; set; } = 5000;
        public bool AbortOnConnectFail { get; set; } = true;
        public bool AllowAdmin { get; set; } = false;
    }

    /// <summary>
    /// 缓存状态
    /// </summary>
    public class CacheStatus
    {
        public DateTime Timestamp { get; set; }
        public bool DistributedCacheEnabled { get; set; }
        public bool RedisEnabled { get; set; }
        public bool DistributedCacheHealthy { get; set; }
        public bool RedisHealthy { get; set; }
    }

    /// <summary>
    /// 缓存统计信息
    /// </summary>
    public class CacheStatistics
    {
        public DateTime Timestamp { get; set; }
        public long OperationCount { get; set; }
        public double CacheHitRate { get; set; }
        public long MemoryUsage { get; set; }
    }

    /// <summary>
    /// 系统配置
    /// </summary>
    public class SystemConfig
    {
        public bool CacheEnabled { get; set; }
        public double CacheTimeout { get; set; }
        public string CacheVersion { get; set; }
        public DateTime WarmUpTime { get; set; }
    }

    /// <summary>
    /// 权限配置
    /// </summary>
    public class PermissionsConfig
    {
        public string[] DefaultPermissions { get; set; }
        public string[] AdminPermissions { get; set; }
        public bool CacheEnabled { get; set; }
    }

    /// <summary>
    /// 缓存模块
    /// </summary>
    [DependsOn(
        typeof(AbpCachingModule)
    )]
    public class AgentPlatformCachingModule : AbpModule
    {
        public override void ConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();
            
            // 配置缓存选项
            context.Services.Configure<CacheOptions>(configuration.GetSection("Cache"));
            context.Services.Configure<RedisOptions>(configuration.GetSection("Cache:Redis"));
            
            // 注册缓存服务
            context.Services.AddSingleton<DistributedCacheService>();
            context.Services.AddSingleton<RedisCacheService>();
            context.Services.AddSingleton<CacheConfigurationService>();
            // context.Services.AddHostedService<CacheBackgroundService>();
            
            // 注册缓存健康检查
            context.Services.AddSingleton<CacheHealthCheck>();
        }

        public override async Task OnApplicationInitializationAsync(ApplicationInitializationContext context)
        {
            var cacheConfigurationService = context.ServiceProvider.GetService<CacheConfigurationService>();
            if (cacheConfigurationService != null)
            {
                await cacheConfigurationService.ConfigureCacheAsync();
            }
        }
    }
}